#include <brpc/server.h>
#include <butil/logging.h>
#include <chrono>

#include "data_es.hpp"       // Elasticsearch 数据管理客户端封装
#include "data_redis.hpp"    // Redis 数据管理客户端封装
#include "mysql_user.hpp"    // MySQL 用户管理客户端封装
#include "etcd.hpp"          // 服务注册模块封装
#include "logger.hpp"        // 日志模块封装
#include "utils.hpp"         // 基础工具接口
#include "dms.hpp"           // 短信平台 SDK 模块封装
#include "channel.hpp"       // 信道管理模块封装

#include "user.hxx"
#include "user-odb.hxx"

#include "user.pb.h"         // Protobuf 生成的用户服务代码
#include "base.pb.h"         // Protobuf 生成的基础服务代码
#include "file.pb.h"         // Protobuf 生成的文件服务代码

namespace mag { 

class UserServiceImpl : public mag::UserService {
public:
    /**
     * @brief 构造函数，初始化各个管理模块并创建 ES 索引
     * 
     * @param dms_client 短信服务客户端
     * @param es_client Elasticsearch 客户端
     * @param mysql_client MySQL 数据库客户端
     * @param redis_client Redis 数据库客户端
     * @param channel_manager 信道管理器
     * @param file_service_name 文件服务名称
     */
    UserServiceImpl(const DMSClient::ptr &dms_client,
                   const std::shared_ptr<elasticlient::Client> &es_client,
                   const std::shared_ptr<odb::core::database> &mysql_client,
                   const std::shared_ptr<sw::redis::Redis> &redis_client,
                   const ServiceManager::ptr &channel_manager,
                   const std::string &file_service_name) :
        _es_user(std::make_shared<ESUser>(es_client)),
        _mysql_user(std::make_shared<UserTable>(mysql_client)),
        _redis_session(std::make_shared<Session>(redis_client)),
        _redis_status(std::make_shared<Status>(redis_client)),
        _redis_codes(std::make_shared<Codes>(redis_client)),
        _file_service_name(file_service_name),
        _mm_channels(channel_manager),
        _dms_client(dms_client) {
            _es_user->createIndex(); // 创建 Elasticsearch 索引
            LOG_INFO("UserServiceImpl 初始化完成，Elasticsearch 索引已创建。");
    }

    ~UserServiceImpl() {}

    ////////////////////////////////
    /// 辅助函数
    ////////////////////////////////

    /**
     * @brief 检查昵称长度是否小于22个字符
     * 
     * @param nickname 用户昵称
     * @return true 合法
     * @return false 不合法
     */
    bool nickname_check(const std::string &nickname) {
        return nickname.size() < 22;
    }

    /**
     * @brief 检查密码长度和字符合法性
     * 
     * @param password 用户密码
     * @return true 合法
     * @return false 不合法
     */
    bool password_check(const std::string &password) {
        if (password.size() < 6 || password.size() > 15) {
            LOG_ERROR("密码长度不合法：{}-{}", password, password.size());
            return false;
        }
        for (char ch : password) {
            if (!((ch >= 'a' && ch <= 'z') ||
                  (ch >= 'A' && ch <= 'Z') ||
                  (ch >= '0' && ch <= '9') ||
                  ch == '_' || ch == '-')) {
                LOG_ERROR("密码字符不合法：{}", password);
                return false;
            }
        }
        return true;
    }

    /**
     * @brief 检查手机号码格式是否正确
     * 
     * @param phone 手机号码
     * @return true 合法
     * @return false 不合法
     */
    bool phone_check(const std::string &phone) {
        if (phone.size() != 11) return false;
        if (phone[0] != '1') return false;
        if (phone[1] < '3' || phone[1] > '9') return false;
        for (size_t i = 2; i < phone.size(); ++i) {
            if (phone[i] < '0' || phone[i] > '9') return false;
        }
        return true;
    }

    ////////////////////////////////
    /// RPC 方法实现
    ////////////////////////////////

    /**
     * @brief 用户注册
     * 
     * @param controller RPC 控制器
     * @param request 用户注册请求
     * @param response 用户注册响应
     * @param done RPC 完成回调
     */
    virtual void UserRegister(::google::protobuf::RpcController* controller,
                              const ::mag::UserRegisterReq* request,
                              ::mag::UserRegisterRsp* response,
                              ::google::protobuf::Closure* done) override {
        LOG_INFO("进入 UserRegister 方法，Request ID: {}", request->request_id());
        auto start_time = std::chrono::steady_clock::now();
        brpc::ClosureGuard rpc_guard(done);

        // 错误响应辅助函数
        auto err_response = [this, response](const std::string &rid, 
                                             const std::string &errmsg) -> void {
            response->set_request_id(rid);
            response->set_success(false);
            response->set_errmsg(errmsg);
            LOG_WARN("Request ID: {} - 错误: {}", rid, errmsg);
        };
        
        try {
            // 1. 提取昵称和密码
            std::string nickname = request->nickname();
            std::string password = request->password();
            LOG_DEBUG("Request ID: {} - 提取昵称: {}, 密码长度: {}", 
                      request->request_id(), nickname, password.size());
            
            // 2. 检查昵称合法性
            if (!nickname_check(nickname)) {
                LOG_ERROR("Request ID: {} - 用户名长度不合法！", request->request_id());
                return err_response(request->request_id(), "用户名长度不合法！");
            }
            
            // 3. 检查密码合法性
            if (!password_check(password)) {
                LOG_ERROR("Request ID: {} - 密码格式不合法！", request->request_id());
                return err_response(request->request_id(), "密码格式不合法！");
            }
            
            // 4. 检查昵称是否已存在
            auto user = _mysql_user->select_by_nickname(nickname);
            if (user) {
                LOG_ERROR("Request ID: {} - 用户名被占用 - {}！", request->request_id(), nickname);
                return err_response(request->request_id(), "用户名被占用!");
            }
            
            // 5. 向数据库新增用户
            std::string uid = uuid();
            user = std::make_shared<User>(uid, nickname, password);
            if (!_mysql_user->insert(user)) {
                LOG_ERROR("Request ID: {} - MySQL 数据库新增数据失败！", request->request_id());
                return err_response(request->request_id(), "MySQL 数据库新增数据失败!");
            }
            LOG_INFO("Request ID: {} - 新用户已插入 MySQL，UID: {}", request->request_id(), uid);
            
            // 6. 向 Elasticsearch 服务器新增用户信息
            if (!_es_user->appendData(uid, "", nickname, "", "")) {
                LOG_ERROR("Request ID: {} - Elasticsearch 搜索引擎新增数据失败！", request->request_id());
                return err_response(request->request_id(), "Elasticsearch 搜索引擎新增数据失败！");
            }
            LOG_INFO("Request ID: {} - 新用户信息已同步到 Elasticsearch，UID: {}", request->request_id(), uid);
            
            // 7. 组织成功响应
            response->set_request_id(request->request_id());
            response->set_success(true);
            LOG_INFO("Request ID: {} - UserRegister 成功，耗时: {} ms", 
                     request->request_id(), 
                     std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time).count());
        } catch (const std::exception &e) {
            LOG_FATAL("Request ID: {} - 异常捕获: {}", request->request_id(), e.what());
            err_response(request->request_id(), "服务器内部错误！");
        } catch (...) {
            LOG_FATAL("Request ID: {} - 未知异常捕获！", request->request_id());
            err_response(request->request_id(), "服务器内部错误！");
        }
    }

    /**
     * @brief 用户登录
     * 
     * @param controller RPC 控制器
     * @param request 用户登录请求
     * @param response 用户登录响应
     * @param done RPC 完成回调
     */
    virtual void UserLogin(::google::protobuf::RpcController* controller,
                           const ::mag::UserLoginReq* request,
                           ::mag::UserLoginRsp* response,
                           ::google::protobuf::Closure* done) override {
        LOG_INFO("进入 UserLogin 方法，Request ID: {}", request->request_id());
        auto start_time = std::chrono::steady_clock::now();
        brpc::ClosureGuard rpc_guard(done);

        // 错误响应辅助函数
        auto err_response = [this, response](const std::string &rid, 
                                             const std::string &errmsg) -> void {
            response->set_request_id(rid);
            response->set_success(false);
            response->set_errmsg(errmsg);
            LOG_WARN("Request ID: {} - 错误: {}", rid, errmsg);
        };
        
        try {
            // 1. 提取昵称和密码
            std::string nickname = request->nickname();
            std::string password = request->password();
            LOG_DEBUG("Request ID: {} - 提取昵称: {}, 密码长度: {}", 
                      request->request_id(), nickname, password.size());
            
            // 2. 验证用户信息
            auto user = _mysql_user->select_by_nickname(nickname);
            if (!user || password != user->password()) {
                LOG_ERROR("Request ID: {} - 用户名或密码错误 - {}-{}！", 
                          request->request_id(), nickname, password);
                return err_response(request->request_id(), "用户名或密码错误!");
            }
            LOG_INFO("Request ID: {} - 用户 {} 验证成功，UID: {}", 
                     request->request_id(), nickname, user->user_id());
            
            // 3. 检查用户是否已登录
            if (_redis_status->exists(user->user_id())) {
                LOG_ERROR("Request ID: {} - 用户已在其他地方登录 - {}！", 
                          request->request_id(), nickname);
                return err_response(request->request_id(), "用户已在其他地方登录!");
            }
            
            // 4. 生成会话ID并存储会话信息
            std::string ssid = uuid();
            _redis_session->append(ssid, user->user_id());
            LOG_DEBUG("Request ID: {} - 会话ID生成: {}", request->request_id(), ssid);
            
            // 5. 添加用户登录标记
            _redis_status->append(user->user_id());
            LOG_INFO("Request ID: {} - 用户 {} 登录标记已添加。", 
                     request->request_id(), nickname);
            
            // 6. 返回成功响应
            response->set_request_id(request->request_id());
            response->set_login_session_id(ssid);
            response->set_success(true);
            LOG_INFO("Request ID: {} - UserLogin 成功，耗时: {} ms", 
                     request->request_id(), 
                     std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time).count());
        } catch (const std::exception &e) {
            LOG_FATAL("Request ID: {} - 异常捕获: {}", request->request_id(), e.what());
            err_response(request->request_id(), "服务器内部错误！");
        } catch (...) {
            LOG_FATAL("Request ID: {} - 未知异常捕获！", request->request_id());
            err_response(request->request_id(), "服务器内部错误！");
        }
    }

    /**
     * @brief 获取手机验证码
     * 
     * @param controller RPC 控制器
     * @param request 获取验证码请求
     * @param response 获取验证码响应
     * @param done RPC 完成回调
     */
    virtual void GetPhoneVerifyCode(::google::protobuf::RpcController* controller,
                                    const ::mag::PhoneVerifyCodeReq* request,
                                    ::mag::PhoneVerifyCodeRsp* response,
                                    ::google::protobuf::Closure* done) override {
        LOG_INFO("进入 GetPhoneVerifyCode 方法，Request ID: {}", request->request_id());
        auto start_time = std::chrono::steady_clock::now();
        brpc::ClosureGuard rpc_guard(done);

        // 错误响应辅助函数
        auto err_response = [this, response](const std::string &rid, 
                                             const std::string &errmsg) -> void {
            response->set_request_id(rid);
            response->set_success(false);
            response->set_errmsg(errmsg);
            LOG_WARN("Request ID: {} - 错误: {}", rid, errmsg);
        };

        try {
            // 1. 请求中获取手机号并验证
            std::string phone = request->phone_number();
            LOG_DEBUG("Request ID: {} - 提取手机号码: {}", request->request_id(), phone);
            if (!phone_check(phone)) {
                LOG_ERROR("Request ID: {} - 手机号码格式错误 - {}！", 
                          request->request_id(), phone);
                return err_response(request->request_id(), "手机号码格式错误");
            }

            // 2. 生成4位验证码
            std::string code_id = uuid();
            std::string code = vcode(); // 假设 vcode() 生成随机验证码
            LOG_DEBUG("Request ID: {} - 生成验证码ID: {}, 验证码: {}", 
                      request->request_id(), code_id, code);

            // 3. 发送验证码
            if (!_dms_client->send(phone, code)) {
                LOG_ERROR("Request ID: {} - 短信验证码发送失败 - {}！", 
                          request->request_id(), phone);
                return err_response(request->request_id(), "短信验证码发送失败!");
            }
            LOG_INFO("Request ID: {} - 短信验证码已发送到 {}", request->request_id(), phone);

            // 4. 构造验证码ID并添加到 Redis 中
            _redis_codes->append(code_id, code);
            LOG_DEBUG("Request ID: {} - 验证码ID: {} 已存储到 Redis", 
                      request->request_id(), code_id);

            // 5. 组织响应，返回生成的验证码ID
            response->set_request_id(request->request_id());
            response->set_success(true);
            response->set_verify_code_id(code_id);
            LOG_INFO("Request ID: {} - GetPhoneVerifyCode 成功，耗时: {} ms", 
                     request->request_id(), 
                     std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time).count());
        } catch (const std::exception &e) {
            LOG_FATAL("Request ID: {} - 异常捕获: {}", request->request_id(), e.what());
            err_response(request->request_id(), "服务器内部错误！");
        } catch (...) {
            LOG_FATAL("Request ID: {} - 未知异常捕获！", request->request_id());
            err_response(request->request_id(), "服务器内部错误！");
        }
    }

    /**
     * @brief 手机号注册
     * 
     * @param controller RPC 控制器
     * @param request 手机号注册请求
     * @param response 手机号注册响应
     * @param done RPC 完成回调
     */
    virtual void PhoneRegister(::google::protobuf::RpcController* controller,
                               const ::mag::PhoneRegisterReq* request,
                               ::mag::PhoneRegisterRsp* response,
                               ::google::protobuf::Closure* done) override {
        LOG_INFO("进入 PhoneRegister 方法，Request ID: {}", request->request_id());
        auto start_time = std::chrono::steady_clock::now();
        brpc::ClosureGuard rpc_guard(done);

        // 错误响应辅助函数
        auto err_response = [this, response](const std::string &rid, 
                                             const std::string &errmsg) -> void {
            response->set_request_id(rid);
            response->set_success(false);
            response->set_errmsg(errmsg);
            LOG_WARN("Request ID: {} - 错误: {}", rid, errmsg);
        };

        try {
            // 1. 从请求中取出手机号码、验证码ID和验证码
            std::string phone = request->phone_number();
            std::string code_id = request->verify_code_id();
            std::string code = request->verify_code();
            LOG_DEBUG("Request ID: {} - 提取手机号码: {}, 验证码ID: {}, 验证码: {}", 
                      request->request_id(), phone, code_id, code);

            // 2. 检查注册手机号码是否合法
            if (!phone_check(phone)) {
                LOG_ERROR("Request ID: {} - 手机号码格式错误 - {}！", 
                          request->request_id(), phone);
                return err_response(request->request_id(), "手机号码格式错误!");
            }

            // 3. 从 Redis 数据库中进行验证码ID与验证码一致性匹配
            std::string vcode = _redis_codes->code(code_id).value_or("");
            if (vcode != code) {
                LOG_ERROR("Request ID: {} - 验证码错误 - {}-{}！", 
                          request->request_id(), code_id, code);
                return err_response(request->request_id(), "验证码错误!");
            }
            // 删除验证码，防止重复使用
            _redis_codes->remove(code_id);
            LOG_DEBUG("Request ID: {} - 验证码ID: {} 验证成功，已从 Redis 中删除。", 
                      request->request_id(), code_id);

            // 4. 检查手机号是否已注册
            auto user = _mysql_user->select_by_phone(phone);
            if (user) {
                LOG_ERROR("Request ID: {} - 该手机号已注册过用户 - {}！", 
                          request->request_id(), phone);
                return err_response(request->request_id(), "该手机号已注册过用户!");
            }

            // 5. 向数据库新增用户信息
            std::string uid = uuid();
            user = std::make_shared<User>(uid, phone);
            if (!_mysql_user->insert(user)) {
                LOG_ERROR("Request ID: {} - 向数据库添加用户信息失败 - {}！", 
                          request->request_id(), phone);
                return err_response(request->request_id(), "向数据库添加用户信息失败!");
            }
            LOG_INFO("Request ID: {} - 新用户已插入 MySQL，UID: {}", 
                     request->request_id(), uid);

            // 6. 向 Elasticsearch 服务器中新增用户信息
            if (!_es_user->appendData(uid, phone, uid, "", "")) {
                LOG_ERROR("Request ID: {} - Elasticsearch 搜索引擎新增数据失败！", 
                          request->request_id());
                return err_response(request->request_id(), "Elasticsearch 搜索引擎新增数据失败！");
            }
            LOG_INFO("Request ID: {} - 新用户信息已同步到 Elasticsearch，UID: {}", 
                     request->request_id(), uid);

            // 7. 组织成功响应
            response->set_request_id(request->request_id());
            response->set_success(true);
            LOG_INFO("Request ID: {} - PhoneRegister 成功，耗时: {} ms", 
                     request->request_id(), 
                     std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time).count());
        } catch (const std::exception &e) {
            LOG_FATAL("Request ID: {} - 异常捕获: {}", request->request_id(), e.what());
            err_response(request->request_id(), "服务器内部错误！");
        } catch (...) {
            LOG_FATAL("Request ID: {} - 未知异常捕获！", request->request_id());
            err_response(request->request_id(), "服务器内部错误！");
        }
    }

    /**
     * @brief 手机号登录
     * 
     * @param controller RPC 控制器
     * @param request 手机号登录请求
     * @param response 手机号登录响应
     * @param done RPC 完成回调
     */
    virtual void PhoneLogin(::google::protobuf::RpcController* controller,
                            const ::mag::PhoneLoginReq* request,
                            ::mag::PhoneLoginRsp* response,
                            ::google::protobuf::Closure* done) override {
        LOG_INFO("进入 PhoneLogin 方法，Request ID: {}", request->request_id());
        auto start_time = std::chrono::steady_clock::now();
        brpc::ClosureGuard rpc_guard(done);

        // 错误响应辅助函数
        auto err_response = [this, response](const std::string &rid, 
                                             const std::string &errmsg) -> void {
            response->set_request_id(rid);
            response->set_success(false);
            response->set_errmsg(errmsg);
            LOG_WARN("Request ID: {} - 错误: {}", rid, errmsg);
        };

        try {
            // 1. 从请求中取出手机号码、验证码ID和验证码
            std::string phone = request->phone_number();
            std::string code_id = request->verify_code_id();
            std::string code = request->verify_code();
            LOG_DEBUG("Request ID: {} - 提取手机号码: {}, 验证码ID: {}, 验证码: {}", 
                      request->request_id(), phone, code_id, code);

            // 2. 检查手机号码是否合法
            if (!phone_check(phone)) {
                LOG_ERROR("Request ID: {} - 手机号码格式错误 - {}！", 
                          request->request_id(), phone);
                return err_response(request->request_id(), "手机号码格式错误!");
            }

            // 3. 根据手机号查询用户信息，判断用户是否存在
            auto user = _mysql_user->select_by_phone(phone);
            if (!user) {
                LOG_ERROR("Request ID: {} - 该手机号未注册用户 - {}！", 
                          request->request_id(), phone);
                return err_response(request->request_id(), "该手机号未注册用户!");
            }
            LOG_INFO("Request ID: {} - 用户 {} 存在，UID: {}", 
                     request->request_id(), phone, user->user_id());

            // 4. 从 Redis 数据库中进行验证码ID与验证码一致性匹配
            std::string vcode = _redis_codes->code(code_id).value_or("");
            if (vcode != code) {
                LOG_ERROR("Request ID: {} - 验证码错误 - {}-{}！", 
                          request->request_id(), code_id, code);
                return err_response(request->request_id(), "验证码错误!");
            }
            // 删除验证码，防止重复使用
            _redis_codes->remove(code_id);
            LOG_DEBUG("Request ID: {} - 验证码ID: {} 验证成功，已从 Redis 中删除。", 
                      request->request_id(), code_id);

            // 5. 检查用户是否已登录
            if (_redis_status->exists(user->user_id())) {
                LOG_ERROR("Request ID: {} - 用户已在其他地方登录 - {}！", 
                          request->request_id(), phone);
                return err_response(request->request_id(), "用户已在其他地方登录!");
            }

            // 6. 生成会话ID并存储会话信息
            std::string ssid = uuid();
            _redis_session->append(ssid, user->user_id());
            LOG_DEBUG("Request ID: {} - 会话ID生成: {}", request->request_id(), ssid);

            // 7. 添加用户登录标记
            _redis_status->append(user->user_id());
            LOG_INFO("Request ID: {} - 用户 {} 登录标记已添加。", 
                     request->request_id(), phone);

            // 8. 返回成功响应
            response->set_request_id(request->request_id());
            response->set_login_session_id(ssid);
            response->set_success(true);
            LOG_INFO("Request ID: {} - PhoneLogin 成功，耗时: {} ms", 
                     request->request_id(), 
                     std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time).count());
        } catch (const std::exception &e) {
            LOG_FATAL("Request ID: {} - 异常捕获: {}", request->request_id(), e.what());
            err_response(request->request_id(), "服务器内部错误！");
        } catch (...) {
            LOG_FATAL("Request ID: {} - 未知异常捕获！", request->request_id());
            err_response(request->request_id(), "服务器内部错误！");
        }
    }

    /**
     * @brief 获取单个用户信息
     * 
     * @param controller RPC 控制器
     * @param request 获取用户信息请求
     * @param response 获取用户信息响应
     * @param done RPC 完成回调
     */
    virtual void GetUserInfo(::google::protobuf::RpcController* controller,
                             const ::mag::GetUserInfoReq* request,
                             ::mag::GetUserInfoRsp* response,
                             ::google::protobuf::Closure* done) override {
        LOG_INFO("进入 GetUserInfo 方法，Request ID: {}", request->request_id());
        auto start_time = std::chrono::steady_clock::now();
        brpc::ClosureGuard rpc_guard(done);

        // 错误响应辅助函数
        auto err_response = [this, response](const std::string &rid, 
                                             const std::string &errmsg) -> void {
            response->set_request_id(rid);
            response->set_success(false);
            response->set_errmsg(errmsg);
            LOG_WARN("Request ID: {} - 错误: {}", rid, errmsg);
        };

        try {
            // 1. 提取用户ID
            std::string uid = request->user_id();
            LOG_DEBUG("Request ID: {} - 提取用户ID: {}", request->request_id(), uid);

            // 2. 从数据库中查询用户信息
            auto user = _mysql_user->select_by_id(uid);
            if (!user) {
                LOG_ERROR("Request ID: {} - 未找到用户信息 - {}！", 
                          request->request_id(), uid);
                return err_response(request->request_id(), "未找到用户信息!");
            }
            LOG_INFO("Request ID: {} - 找到用户信息，UID: {}", 
                     request->request_id(), uid);

            // 3. 获取用户头像
            UserInfo *user_info = response->mutable_user_info();
            user_info->set_user_id(user->user_id());
            user_info->set_nickname(user->nickname());
            user_info->set_description(user->description());
            user_info->set_phone(user->phone());

            if (!user->avatar_id().empty()) {
                auto channel = _mm_channels->choose(_file_service_name);
                if (!channel) {
                    LOG_ERROR("Request ID: {} - 未找到文件管理子服务节点 - {} - {}！", 
                              request->request_id(), _file_service_name, uid);
                    return err_response(request->request_id(), "未找到文件管理子服务节点!");
                }

                // 调用文件服务获取头像
                mag::FileService_Stub stub(channel.get());
                mag::GetSingleFileReq file_req;
                mag::GetSingleFileRsp file_rsp;
                file_req.set_request_id(request->request_id());
                file_req.set_file_id(user->avatar_id());
                brpc::Controller cntl;
                stub.GetSingleFile(&cntl, &file_req, &file_rsp, nullptr);

                if (cntl.Failed() || !file_rsp.success()) {
                    LOG_ERROR("Request ID: {} - 文件子服务调用失败：{}！", 
                              request->request_id(), cntl.ErrorText());
                    return err_response(request->request_id(), "文件子服务调用失败!");
                }

                user_info->set_avatar(file_rsp.file_data().file_content());
                LOG_DEBUG("Request ID: {} - 获取用户头像成功，File ID: {}", 
                          request->request_id(), user->avatar_id());
            }

            // 4. 返回成功响应
            response->set_request_id(request->request_id());
            response->set_success(true);
            LOG_INFO("Request ID: {} - GetUserInfo 成功，耗时: {} ms", 
                     request->request_id(), 
                     std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time).count());
        } catch (const std::exception &e) {
            LOG_FATAL("Request ID: {} - 异常捕获: {}", request->request_id(), e.what());
            err_response(request->request_id(), "服务器内部错误！");
        } catch (...) {
            LOG_FATAL("Request ID: {} - 未知异常捕获！", request->request_id());
            err_response(request->request_id(), "服务器内部错误！");
        }
    }

    /**
     * @brief 批量获取多个用户的信息，包括头像数据
     * 
     * @param controller RPC 控制器
     * @param request 批量获取用户信息请求
     * @param response 批量获取用户信息响应
     * @param done RPC 完成回调
     */
    virtual void GetMultiUserInfo(::google::protobuf::RpcController* controller,
                                  const ::mag::GetMultiUserInfoReq* request,
                                  ::mag::GetMultiUserInfoRsp* response,
                                  ::google::protobuf::Closure* done) override {
        LOG_INFO("进入 GetMultiUserInfo 方法，Request ID: {}", request->request_id());
        auto start_time = std::chrono::steady_clock::now();
        brpc::ClosureGuard rpc_guard(done);

        // 错误响应辅助函数
        auto err_response = [this, response](const std::string &rid, 
                                             const std::string &errmsg) -> void {
            response->set_request_id(rid);
            response->set_success(false);
            response->set_errmsg(errmsg);
            LOG_WARN("Request ID: {} - 错误: {}", rid, errmsg);
        };

        try {
            // 1. 从请求中取出用户ID列表
            std::vector<std::string> uid_lists;
            for (int i = 0; i < request->users_id_size(); ++i) {
                uid_lists.push_back(request->users_id(i));
            }
            LOG_DEBUG("Request ID: {} - 提取用户ID列表，共 {} 个用户", 
                      request->request_id(), uid_lists.size());

            // 2. 从数据库进行批量用户信息查询
            auto users = _mysql_user->select_multi_users(uid_lists);
            if (users.size() != static_cast<size_t>(request->users_id_size())) {
                LOG_ERROR("Request ID: {} - 从数据库查找的用户信息数量不一致 {}-{}！", 
                          request->request_id(), request->users_id_size(), users.size());
                return err_response(request->request_id(), "从数据库查找的用户信息数量不一致!");
            }
            LOG_INFO("Request ID: {} - 从数据库查找用户信息成功，共找到 {} 个用户", 
                     request->request_id(), users.size());

            // 3. 批量从文件管理子服务进行文件下载
            auto channel = _mm_channels->choose(_file_service_name);
            if (!channel) {
                LOG_ERROR("Request ID: {} - 未找到文件管理子服务节点 - {}！", 
                          request->request_id(), _file_service_name);
                return err_response(request->request_id(), "未找到文件管理子服务节点!");
            }

            // 调用文件服务获取多个头像
            mag::FileService_Stub stub(channel.get());
            mag::GetMultiFileReq file_req;
            mag::GetMultiFileRsp file_rsp;
            file_req.set_request_id(request->request_id());
            for (auto &user : users) {
                if (!user.avatar_id().empty()) {
                    file_req.add_file_id_list(user.avatar_id());
                }
            }
            LOG_DEBUG("Request ID: {} - 调用文件服务获取头像，共请求 {} 个文件", 
                      request->request_id(), file_req.file_id_list_size());

            brpc::Controller cntl;
            stub.GetMultiFile(&cntl, &file_req, &file_rsp, nullptr);

            if (cntl.Failed() || !file_rsp.success()) {
                LOG_ERROR("Request ID: {} - 文件子服务调用失败：{} - {}！", 
                          request->request_id(), _file_service_name, cntl.ErrorText());
                return err_response(request->request_id(), "文件子服务调用失败!");
            }
            LOG_INFO("Request ID: {} - 文件子服务调用成功，获取 {} 个头像", 
                     request->request_id(), file_rsp.file_data_size());

            // 4. 组织响应
            auto user_map = response->mutable_users_info(); // 响应的用户信息映射
            auto file_map = file_rsp.mutable_file_data();   // 文件服务的文件数据映射

            for (auto &user : users) {
                UserInfo user_info;
                user_info.set_user_id(user.user_id());
                user_info.set_nickname(user.nickname());
                user_info.set_description(user.description());
                user_info.set_phone(user.phone());

                if (!user.avatar_id().empty() && file_map->find(user.avatar_id()) != file_map->end()) {
                    user_info.set_avatar((*file_map)[user.avatar_id()].file_content());
                    LOG_DEBUG("Request ID: {} - 用户 {} 的头像已获取", 
                              request->request_id(), user.user_id());
                }

                (*user_map)[user_info.user_id()] = user_info;
            }

            // 5. 返回成功响应
            response->set_request_id(request->request_id());
            response->set_success(true);
            LOG_INFO("Request ID: {} - GetMultiUserInfo 成功，耗时: {} ms", 
                     request->request_id(), 
                     std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time).count());
        } catch (const std::exception &e) {
            LOG_FATAL("Request ID: {} - 异常捕获: {}", request->request_id(), e.what());
            err_response(request->request_id(), "服务器内部错误！");
        } catch (...) {
            LOG_FATAL("Request ID: {} - 未知异常捕获！", request->request_id());
            err_response(request->request_id(), "服务器内部错误！");
        }
    }

    /**
     * @brief 设置用户头像，上传头像文件到文件服务，并更新数据库和 ES
     * 
     * @param controller RPC 控制器
     * @param request 设置头像请求
     * @param response 设置头像响应
     * @param done RPC 完成回调
     */
    virtual void SetUserAvatar(::google::protobuf::RpcController* controller,
                               const ::mag::SetUserAvatarReq* request,
                               ::mag::SetUserAvatarRsp* response,
                               ::google::protobuf::Closure* done) override {
        LOG_INFO("进入 SetUserAvatar 方法，Request ID: {}", request->request_id());
        auto start_time = std::chrono::steady_clock::now();
        brpc::ClosureGuard rpc_guard(done);

        // 错误响应辅助函数
        auto err_response = [this, response](const std::string &rid, 
                                             const std::string &errmsg) -> void {
            response->set_request_id(rid);
            response->set_success(false);
            response->set_errmsg(errmsg);
            LOG_WARN("Request ID: {} - 错误: {}", rid, errmsg);
        };

        try {
            // 1. 从请求中取出用户 ID 与头像数据
            std::string uid = request->user_id();
            std::string avatar_data = request->avatar();
            LOG_DEBUG("Request ID: {} - 提取用户ID: {}, 头像数据大小: {}", 
                      request->request_id(), uid, avatar_data.size());

            // 2. 从数据库查询用户信息，判断用户是否存在
            auto user = _mysql_user->select_by_id(uid);
            if (!user) {
                LOG_ERROR("Request ID: {} - 未找到用户信息 - {}！", 
                          request->request_id(), uid);
                return err_response(request->request_id(), "未找到用户信息!");
            }
            LOG_INFO("Request ID: {} - 找到用户信息，UID: {}", 
                     request->request_id(), uid);

            // 3. 上传头像文件到文件服务
            auto channel = _mm_channels->choose(_file_service_name);
            if (!channel) {
                LOG_ERROR("Request ID: {} - 未找到文件管理子服务节点 - {}！", 
                          request->request_id(), _file_service_name);
                return err_response(request->request_id(), "未找到文件管理子服务节点!");
            }

            mag::FileService_Stub stub(channel.get());
            mag::PutSingleFileReq file_req;
            mag::PutSingleFileRsp file_rsp;
            file_req.set_request_id(request->request_id());
            file_req.mutable_file_data()->set_file_name(""); // 可根据需要设置文件名
            file_req.mutable_file_data()->set_file_size(avatar_data.size());
            file_req.mutable_file_data()->set_file_content(avatar_data);
            LOG_DEBUG("Request ID: {} - 上传头像文件，文件大小: {}", 
                      request->request_id(), avatar_data.size());

            brpc::Controller cntl;
            stub.PutSingleFile(&cntl, &file_req, &file_rsp, nullptr);

            if (cntl.Failed() || !file_rsp.success()) {
                LOG_ERROR("Request ID: {} - 文件子服务调用失败：{}！", 
                          request->request_id(), cntl.ErrorText());
                return err_response(request->request_id(), "文件子服务调用失败!");
            }
            LOG_INFO("Request ID: {} - 头像文件上传成功，File ID: {}", 
                     request->request_id(), file_rsp.file_info().file_id());

            std::string avatar_id = file_rsp.file_info().file_id();

            // 4. 更新数据库中的头像ID
            user->avatar_id(avatar_id);
            if (!_mysql_user->update(user)) {
                LOG_ERROR("Request ID: {} - 更新数据库用户头像ID失败 ：{}！", 
                          request->request_id(), avatar_id);
                return err_response(request->request_id(), "更新数据库用户头像ID失败!");
            }
            LOG_INFO("Request ID: {} - 数据库中用户 {} 的头像ID 已更新为 {}", 
                     request->request_id(), uid, avatar_id);

            // 5. 更新 Elasticsearch 中的用户信息
            if (!_es_user->appendData(user->user_id(), user->phone(),
                                       user->nickname(), user->description(), user->avatar_id())) {
                LOG_ERROR("Request ID: {} - 更新 Elasticsearch 用户头像ID失败 ：{}！", 
                          request->request_id(), avatar_id);
                return err_response(request->request_id(), "更新 Elasticsearch 用户头像ID失败!");
            }
            LOG_INFO("Request ID: {} - Elasticsearch 中用户 {} 的头像ID 已更新为 {}", 
                     request->request_id(), uid, avatar_id);

            // 6. 组织成功响应
            response->set_request_id(request->request_id());
            response->set_success(true);
            LOG_INFO("Request ID: {} - SetUserAvatar 成功，耗时: {} ms", 
                     request->request_id(), 
                     std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time).count());
        } catch (const std::exception &e) {
            LOG_FATAL("Request ID: {} - 异常捕获: {}", request->request_id(), e.what());
            err_response(request->request_id(), "服务器内部错误！");
        } catch (...) {
            LOG_FATAL("Request ID: {} - 未知异常捕获！", request->request_id());
            err_response(request->request_id(), "服务器内部错误！");
        }
    }

    /**
     * @brief 设置用户昵称，更新数据库和 ES
     * 
     * @param controller RPC 控制器
     * @param request 设置昵称请求
     * @param response 设置昵称响应
     * @param done RPC 完成回调
     */
    virtual void SetUserNickname(::google::protobuf::RpcController* controller,
                                 const ::mag::SetUserNicknameReq* request,
                                 ::mag::SetUserNicknameRsp* response,
                                 ::google::protobuf::Closure* done) override {
        LOG_INFO("进入 SetUserNickname 方法，Request ID: {}", request->request_id());
        auto start_time = std::chrono::steady_clock::now();
        brpc::ClosureGuard rpc_guard(done);

        // 错误响应辅助函数
        auto err_response = [this, response](const std::string &rid, 
                                             const std::string &errmsg) -> void {
            response->set_request_id(rid);
            response->set_success(false);
            response->set_errmsg(errmsg);
            LOG_WARN("Request ID: {} - 错误: {}", rid, errmsg);
        };

        try {
            // 1. 从请求中取出用户 ID 与新的昵称
            std::string uid = request->user_id();
            std::string new_nickname = request->nickname();
            LOG_DEBUG("Request ID: {} - 提取用户ID: {}, 新昵称: {}", 
                      request->request_id(), uid, new_nickname);

            // 2. 判断昵称格式是否正确
            if (!nickname_check(new_nickname)) {
                LOG_ERROR("Request ID: {} - 用户名长度不合法！", 
                          request->request_id());
                return err_response(request->request_id(), "用户名长度不合法！");
            }

            // 2.1 检查新的昵称是否已被占用
            auto existing_user = _mysql_user->select_by_nickname(new_nickname);
            if (existing_user && existing_user->user_id() != uid) {
                LOG_ERROR("Request ID: {} - 新昵称已被占用：{}！", 
                          request->request_id(), new_nickname);
                return err_response(request->request_id(), "新昵称已被占用！");
            }
            LOG_DEBUG("Request ID: {} - 新昵称 {} 未被占用或属于当前用户。", 
                      request->request_id(), new_nickname);

            // 3. 从数据库查询用户信息，判断用户是否存在
            auto user = _mysql_user->select_by_id(uid);
            if (!user) {
                LOG_ERROR("Request ID: {} - 未找到用户信息 - {}！", 
                          request->request_id(), uid);
                return err_response(request->request_id(), "未找到用户信息!");
            }
            LOG_INFO("Request ID: {} - 找到用户信息，UID: {}", 
                     request->request_id(), uid);

            // 4. 将新的昵称更新到数据库中
            user->nickname(new_nickname);
            if (!_mysql_user->update(user)) {
                LOG_ERROR("Request ID: {} - 更新数据库用户昵称失败 ：{}！", 
                          request->request_id(), new_nickname);
                return err_response(request->request_id(), "更新数据库用户昵称失败!");
            }
            LOG_INFO("Request ID: {} - 数据库中用户 {} 的昵称已更新为 {}", 
                     request->request_id(), uid, new_nickname);

            // 5. 更新 Elasticsearch 中的用户信息
            if (!_es_user->appendData(user->user_id(), user->phone(),
                                       user->nickname(), user->description(), user->avatar_id())) {
                LOG_ERROR("Request ID: {} - 更新 Elasticsearch 用户昵称失败 ：{}！", 
                          request->request_id(), new_nickname);
                return err_response(request->request_id(), "更新 Elasticsearch 用户昵称失败!");
            }
            LOG_INFO("Request ID: {} - Elasticsearch 中用户 {} 的昵称已更新为 {}", 
                     request->request_id(), uid, new_nickname);

            // 6. 组织成功响应
            response->set_request_id(request->request_id());
            response->set_success(true);
            LOG_INFO("Request ID: {} - SetUserNickname 成功，耗时: {} ms", 
                     request->request_id(), 
                     std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time).count());
        } catch (const std::exception &e) {
            LOG_FATAL("Request ID: {} - 异常捕获: {}", request->request_id(), e.what());
            err_response(request->request_id(), "服务器内部错误！");
        } catch (...) {
            LOG_FATAL("Request ID: {} - 未知异常捕获！", request->request_id());
            err_response(request->request_id(), "服务器内部错误！");
        }
    }

    /**
     * @brief 设置用户描述，更新数据库和 ES
     * 
     * @param controller RPC 控制器
     * @param request 设置描述请求
     * @param response 设置描述响应
     * @param done RPC 完成回调
     */
    virtual void SetUserDescription(::google::protobuf::RpcController* controller,
                                    const ::mag::SetUserDescriptionReq* request,
                                    ::mag::SetUserDescriptionRsp* response,
                                    ::google::protobuf::Closure* done) override {
        LOG_INFO("进入 SetUserDescription 方法，Request ID: {}", request->request_id());
        auto start_time = std::chrono::steady_clock::now();
        brpc::ClosureGuard rpc_guard(done);

        // 错误响应辅助函数
        auto err_response = [this, response](const std::string &rid, 
                                             const std::string &errmsg) -> void {
            response->set_request_id(rid);
            response->set_success(false);
            response->set_errmsg(errmsg);
            LOG_WARN("Request ID: {} - 错误: {}", rid, errmsg);
        };

        try {
            // 1. 从请求中取出用户 ID 与新的描述
            std::string uid = request->user_id();
            std::string new_description = request->description();
            LOG_DEBUG("Request ID: {} - 提取用户ID: {}, 新描述: {}", 
                      request->request_id(), uid, new_description);

            // 2. 验证新的描述格式（例如长度限制）
            const size_t MAX_DESCRIPTION_LENGTH = 200; // 示例限制
            if (new_description.size() > MAX_DESCRIPTION_LENGTH) {
                LOG_ERROR("Request ID: {} - 用户描述长度超出限制！", 
                          request->request_id());
                return err_response(request->request_id(), "用户描述长度超出限制！");
            }
            LOG_DEBUG("Request ID: {} - 用户描述格式验证通过。", 
                      request->request_id());

            // 3. 从数据库查询用户信息，判断用户是否存在
            auto user = _mysql_user->select_by_id(uid);
            if (!user) {
                LOG_ERROR("Request ID: {} - 未找到用户信息 - {}！", 
                          request->request_id(), uid);
                return err_response(request->request_id(), "未找到用户信息!");
            }
            LOG_INFO("Request ID: {} - 找到用户信息，UID: {}", 
                     request->request_id(), uid);

            // 4. 将新的描述更新到数据库中
            user->description(new_description);
            if (!_mysql_user->update(user)) {
                LOG_ERROR("Request ID: {} - 更新数据库用户描述失败 ：{}！", 
                          request->request_id(), new_description);
                return err_response(request->request_id(), "更新数据库用户描述失败!");
            }
            LOG_INFO("Request ID: {} - 数据库中用户 {} 的描述已更新为 {}", 
                     request->request_id(), uid, new_description);

            // 5. 更新 Elasticsearch 中的用户信息
            if (!_es_user->appendData(user->user_id(), user->phone(),
                                       user->nickname(), user->description(), user->avatar_id())) {
                LOG_ERROR("Request ID: {} - 更新 Elasticsearch 用户描述失败 ：{}！", 
                          request->request_id(), new_description);
                return err_response(request->request_id(), "更新 Elasticsearch 用户描述失败!");
            }
            LOG_INFO("Request ID: {} - Elasticsearch 中用户 {} 的描述已更新为 {}", 
                     request->request_id(), uid, new_description);

            // 6. 组织成功响应
            response->set_request_id(request->request_id());
            response->set_success(true);
            LOG_INFO("Request ID: {} - SetUserDescription 成功，耗时: {} ms", 
                     request->request_id(), 
                     std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time).count());
        } catch (const std::exception &e) {
            LOG_FATAL("Request ID: {} - 异常捕获: {}", request->request_id(), e.what());
            err_response(request->request_id(), "服务器内部错误！");
        } catch (...) {
            LOG_FATAL("Request ID: {} - 未知异常捕获！", request->request_id());
            err_response(request->request_id(), "服务器内部错误！");
        }
    }

    /**
     * @brief 设置用户手机号，验证验证码，更新数据库和 ES
     * 
     * @param controller RPC 控制器
     * @param request 设置手机号请求
     * @param response 设置手机号响应
     * @param done RPC 完成回调
     */
    virtual void SetUserPhoneNumber(::google::protobuf::RpcController* controller,
                                    const ::mag::SetUserPhoneNumberReq* request,
                                    ::mag::SetUserPhoneNumberRsp* response,
                                    ::google::protobuf::Closure* done) override {
        LOG_INFO("进入 SetUserPhoneNumber 方法，Request ID: {}", request->request_id());
        auto start_time = std::chrono::steady_clock::now();
        brpc::ClosureGuard rpc_guard(done);

        // 错误响应辅助函数
        auto err_response = [this, response](const std::string &rid, 
                                             const std::string &errmsg) -> void {
            response->set_request_id(rid);
            response->set_success(false);
            response->set_errmsg(errmsg);
            LOG_WARN("Request ID: {} - 错误: {}", rid, errmsg);
        };

        try {
            // 1. 从请求中取出用户 ID、新的手机号、验证码ID和验证码
            std::string uid = request->user_id();
            std::string new_phone = request->phone_number();
            std::string code_id = request->phone_verify_code_id();
            std::string code = request->phone_verify_code();
            LOG_DEBUG("Request ID: {} - 提取用户ID: {}, 新手机号: {}, 验证码ID: {}, 验证码: {}", 
                      request->request_id(), uid, new_phone, code_id, code);

            // 2. 验证验证码
            auto vcode = _redis_codes->code(code_id);
            if (vcode != code) {
                LOG_ERROR("Request ID: {} - 验证码错误 - {}-{}！", 
                          request->request_id(), code_id, code);
                return err_response(request->request_id(), "验证码错误!");
            }
            // 删除验证码，防止重复使用
            _redis_codes->remove(code_id);
            LOG_DEBUG("Request ID: {} - 验证码ID: {} 验证成功，已从 Redis 中删除。", 
                      request->request_id(), code_id);

            // 3. 检查新的手机号是否已被占用
            auto existing_user = _mysql_user->select_by_phone(new_phone);
            if (existing_user && existing_user->user_id() != uid) {
                LOG_ERROR("Request ID: {} - 新手机号已被占用：{}！", 
                          request->request_id(), new_phone);
                return err_response(request->request_id(), "新手机号已被占用！");
            }
            LOG_DEBUG("Request ID: {} - 新手机号 {} 未被占用或属于当前用户。", 
                      request->request_id(), new_phone);

            // 4. 从数据库查询用户信息，判断用户是否存在
            auto user = _mysql_user->select_by_id(uid);
            if (!user) {
                LOG_ERROR("Request ID: {} - 未找到用户信息 - {}！", 
                          request->request_id(), uid);
                return err_response(request->request_id(), "未找到用户信息!");
            }
            LOG_INFO("Request ID: {} - 找到用户信息，UID: {}", 
                     request->request_id(), uid);

            // 5. 将新的手机号更新到数据库中
            user->phone(new_phone);
            if (!_mysql_user->update(user)) {
                LOG_ERROR("Request ID: {} - 更新数据库用户手机号失败 ：{}！", 
                          request->request_id(), new_phone);
                return err_response(request->request_id(), "更新数据库用户手机号失败!");
            }
            LOG_INFO("Request ID: {} - 数据库中用户 {} 的手机号已更新为 {}", 
                     request->request_id(), uid, new_phone);

            // 6. 更新 Elasticsearch 中的用户信息
            if (!_es_user->appendData(user->user_id(), user->phone(),
                                       user->nickname(), user->description(), user->avatar_id())) {
                LOG_ERROR("Request ID: {} - 更新 Elasticsearch 用户手机号失败 ：{}！", 
                          request->request_id(), new_phone);
                return err_response(request->request_id(), "更新 Elasticsearch 用户手机号失败!");
            }
            LOG_INFO("Request ID: {} - Elasticsearch 中用户 {} 的手机号已更新为 {}", 
                     request->request_id(), uid, new_phone);

            // 7. 组织成功响应
            response->set_request_id(request->request_id());
            response->set_success(true);
            LOG_INFO("Request ID: {} - SetUserPhoneNumber 成功，耗时: {} ms", 
                     request->request_id(), 
                     std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start_time).count());
        } catch (const std::exception &e) {
            LOG_FATAL("Request ID: {} - 异常捕获: {}", request->request_id(), e.what());
            err_response(request->request_id(), "服务器内部错误！");
        } catch (...) {
            LOG_FATAL("Request ID: {} - 未知异常捕获！", request->request_id());
            err_response(request->request_id(), "服务器内部错误！");
        }
    }

private:
    // 管理模块的智能指针
    ESUser::ptr _es_user;
    UserTable::ptr _mysql_user;
    Session::ptr _redis_session;
    Status::ptr _redis_status;
    Codes::ptr _redis_codes;

    // RPC 调用客户端相关对象
    std::string _file_service_name;
    ServiceManager::ptr _mm_channels;
    DMSClient::ptr _dms_client;
};

// //////////////////////////////////////////////////
// /// 封装 RPC 服务器及其组件，提供方法启动服务器
// //////////////////////////////////////////////////

class UserServer {
public:
    using ptr = std::shared_ptr<UserServer>;

    /**
     * @brief 构造函数，初始化各个组件
     * 
     * @param service_discoverer 服务发现客户端
     * @param reg_client 服务注册客户端
     * @param es_client Elasticsearch 客户端
     * @param mysql_client MySQL 客户端
     * @param redis_client Redis 客户端
     * @param server brpc 服务器实例
     */
    UserServer(const Discovery::ptr service_discoverer, 
               const Registry::ptr &reg_client,
               const std::shared_ptr<elasticlient::Client> &es_client,
               const std::shared_ptr<odb::core::database> &mysql_client,
               std::shared_ptr<sw::redis::Redis> &redis_client,
               const std::shared_ptr<brpc::Server> &server) :
        _service_discoverer(service_discoverer),
        _registry_client(reg_client),
        _es_client(es_client),
        _mysql_client(mysql_client),
        _redis_client(redis_client),
        _rpc_server(server) {}

    ~UserServer() {}

    /**
     * @brief 启动 RPC 服务器，运行直到被要求退出
     */
    void start() {
        LOG_INFO("RPC 服务器开始运行。");
        _rpc_server->RunUntilAskedToQuit();
        LOG_INFO("RPC 服务器已停止运行。");
    }

private:
    Discovery::ptr _service_discoverer;         // 服务发现客户端
    Registry::ptr _registry_client;             // 服务注册客户端
    std::shared_ptr<elasticlient::Client> _es_client;   // Elasticsearch 客户端
    std::shared_ptr<odb::core::database> _mysql_client; // MySQL 客户端
    std::shared_ptr<sw::redis::Redis> _redis_client;    // Redis 客户端
    std::shared_ptr<brpc::Server> _rpc_server;          // brpc 服务器
};

// //////////////////////////////////////////////////
// /// 建造者类，构建 UserServer 所需要的各个组件
// //////////////////////////////////////////////////

class UserServerBuilder {
public:
    /**
     * @brief 创建 Elasticsearch 客户端
     * 
     * @param host_list Elasticsearch 主机列表
     */
    void make_es_object(const std::vector<std::string> host_list) {
        _es_client = ESClientFactory::create(host_list);
        // LOG_INFO("Elasticsearch 客户端已创建，主机列表: {}", vec_to_str(host_list));
    }

    /**
     * @brief 创建短信服务客户端（DMS）
     * 
     * @param access_key_id 访问密钥ID
     * @param access_key_secret 访问密钥密文
     */
    void make_dms_object(const std::string &access_key_id,
                         const std::string &access_key_secret) {
        _dms_client = std::make_shared<DMSClient>(access_key_id, access_key_secret);
        LOG_INFO("短信服务客户端已创建。");
    }

    /**
     * @brief 创建 MySQL 客户端，支持连接池
     * 
     * @param user MySQL 用户名
     * @param pswd MySQL 密码
     * @param host MySQL 主机地址
     * @param db MySQL 数据库名称
     * @param cset MySQL 字符集
     * @param port MySQL 端口号
     * @param conn_pool_count 连接池大小
     */
    void make_mysql_object(const std::string &user,
                           const std::string &pswd,
                           const std::string &host,
                           const std::string &db,
                           const std::string &cset,
                           int port,
                           int conn_pool_count) {
        _mysql_client = ODBFactory::create(user, pswd, host, db, cset, port, conn_pool_count);
        LOG_INFO("MySQL 客户端已创建，数据库: {}, 主机: {}, 端口: {}", 
                 db, host, port);
    }

    /**
     * @brief 创建 Redis 客户端
     * 
     * @param host Redis 主机地址
     * @param port Redis 端口号
     * @param db Redis 数据库编号
     * @param keep_alive 是否保持连接
     */
    void make_redis_object(const std::string &host,
                           int port,
                           int db,
                           bool keep_alive) {
        _redis_client = RedisClientFactory::create(host, port, db, keep_alive);
        LOG_INFO("Redis 客户端已创建，主机: {}, 端口: {}, 数据库: {}, 保持连接: {}", 
                 host, port, db, keep_alive ? "是" : "否");
    }

    /**
     * @brief 创建服务发现客户端，并设置文件服务名称及信道管理回调
     * 
     * @param reg_host 服务注册中心主机地址
     * @param base_service_name 基础服务名称
     * @param file_service_name 文件服务名称
     */
    void make_discovery_object(const std::string &reg_host,
                               const std::string &base_service_name,
                               const std::string &file_service_name) {
        _file_service_name = file_service_name;
        _mm_channels = std::make_shared<ServiceManager>();
        _mm_channels->declared(file_service_name);
        LOG_DEBUG("设置文件子服务为需添加管理的子服务：{}", file_service_name);

        // 绑定服务上线和下线的回调函数
        auto put_cb = std::bind(&ServiceManager::onServiceOnline, _mm_channels.get(),
                                std::placeholders::_1, std::placeholders::_2);
        auto del_cb = std::bind(&ServiceManager::onServiceOffline, _mm_channels.get(),
                                std::placeholders::_1, std::placeholders::_2);
        _service_discoverer = std::make_shared<Discovery>(reg_host, base_service_name, put_cb, del_cb);
        LOG_INFO("服务发现客户端已创建，注册中心: {}, 基础服务: {}", 
                 reg_host, base_service_name);
    }

    /**
     * @brief 创建服务注册客户端，并注册服务到注册中心
     * 
     * @param reg_host 服务注册中心主机地址
     * @param service_name 服务名称
     * @param access_host 服务访问主机地址
     */
    void make_registry_object(const std::string &reg_host,
                              const std::string &service_name,
                              const std::string &access_host) {
        _registry_client = std::make_shared<Registry>(reg_host);
        _registry_client->registry(service_name, access_host);
        LOG_INFO("服务注册客户端已创建，并注册服务: {} 到访问主机: {}", 
                 service_name, access_host);
    }

    /**
     * @brief 检查所有依赖是否已构造，创建 brpc 服务器并添加服务
     * 
     * @param port RPC 服务器监听端口
     * @param timeout RPC 服务器空闲超时时间（秒）
     * @param num_threads RPC 服务器线程数
     */
    void make_rpc_server(uint16_t port, int32_t timeout, uint8_t num_threads) {
        LOG_INFO("开始构建 RPC 服务器。");

        // 检查依赖组件是否已构造
        if (!_es_client) {
            LOG_ERROR("还未初始化 Elasticsearch 搜索引擎模块！");
            abort();
        }
        if (!_mysql_client) {
            LOG_ERROR("还未初始化 MySQL 数据库模块！");
            abort();
        }
        if (!_redis_client) {
            LOG_ERROR("还未初始化 Redis 数据库模块！");
            abort();
        }
        if (!_mm_channels) {
            LOG_ERROR("还未初始化信道管理模块！");
            abort();
        }
        if (!_dms_client) {
            LOG_ERROR("还未初始化短信平台模块！");
            abort();
        }

        _rpc_server = std::make_shared<brpc::Server>();
        LOG_INFO("brpc 服务器实例已创建。");

        // 创建并添加 UserServiceImpl
        UserServiceImpl* user_service = new UserServiceImpl(_dms_client, _es_client,
                                                            _mysql_client, _redis_client,
                                                            _mm_channels, _file_service_name);
        if (_rpc_server->AddService(user_service, brpc::ServiceOwnership::SERVER_OWNS_SERVICE) == -1) {
            LOG_ERROR("添加 UserServiceImpl RPC 服务失败！");
            abort();
        }
        LOG_INFO("UserServiceImpl RPC 服务已添加到 brpc 服务器。");

        // 创建并添加 SpeechRecognitionServiceImpl（假设已实现）
        // SpeechRecognitionServiceImpl* speech_service = new SpeechRecognitionServiceImpl();
        // if (_rpc_server->AddService(speech_service, brpc::ServiceOwnership::SERVER_OWNS_SERVICE) == -1) {
        //     LOG_ERROR("添加 SpeechRecognitionServiceImpl RPC 服务失败！");
        //     abort();
        // }
        // LOG_INFO("SpeechRecognitionServiceImpl RPC 服务已添加到 brpc 服务器。");

        // 启动 RPC 服务器
        brpc::ServerOptions options;
        options.idle_timeout_sec = timeout;
        options.num_threads = num_threads;
        if (_rpc_server->Start(port, &options) == -1) {
            LOG_ERROR("RPC 服务器启动失败！");
            abort();
        }
        LOG_INFO("RPC 服务器已启动，监听端口: {}", port);
    }

    /**
     * @brief 构建并返回 UserServer 实例
     * 
     * @return UserServer::ptr 构建好的 UserServer 智能指针
     */
    UserServer::ptr build() {
        LOG_INFO("开始构建 UserServer 实例。");

        if (!_service_discoverer) {
            LOG_ERROR("还未初始化服务发现模块！");
            abort();
        }
        if (!_registry_client) {
            LOG_ERROR("还未初始化服务注册模块！");
            abort();
        }
        if (!_rpc_server) {
            LOG_ERROR("还未初始化 RPC 服务器模块！");
            abort();
        }

        UserServer::ptr server = std::make_shared<UserServer>(_service_discoverer, _registry_client,
                                                             _es_client, _mysql_client, _redis_client, _rpc_server);
        LOG_INFO("UserServer 实例已构建完成。");
        return server;
    }

private:
    Registry::ptr _registry_client; // 服务注册客户端

    std::shared_ptr<elasticlient::Client> _es_client;      // Elasticsearch 客户端
    std::shared_ptr<odb::core::database> _mysql_client;    // MySQL 客户端
    std::shared_ptr<sw::redis::Redis> _redis_client;       // Redis 客户端

    std::string _file_service_name;    // 文件服务名称
    ServiceManager::ptr _mm_channels;  // 信道管理器
    Discovery::ptr _service_discoverer; // 服务发现客户端

    std::shared_ptr<DMSClient> _dms_client; // 短信服务客户端

    std::shared_ptr<brpc::Server> _rpc_server; // brpc 服务器
};

// //////////////////////////////////////////////////
// /// 封装 RPC 服务器及其组件，提供方法启动服务器
// //////////////////////////////////////////////////

} // namespace mag



/////////////////////////////////////////////////////////////////////////////////////////////////
///原始版本
////////////////////////////////////////////////////////////////////////////////////////////////




// #include <brpc/server.h>
// #include <butil/logging.h>

// #include "data_es.hpp"      // es数据管理客户端封装
// #include "data_redis.hpp"      // redis数据管理客户端封装
// #include "mysql_user.hpp"      // mysql数据管理客户端封装
// #include "etcd.hpp"     // 服务注册模块封装
// #include "logger.hpp"   // 日志模块封装
// #include "utils.hpp"    // 基础工具接口
// #include "dms.hpp"      // 短信平台SDK模块封装
// #include "channel.hpp"  // 信道管理模块封装

// #include "user.hxx"
// #include "user-odb.hxx"

// #include "user.pb.h"  // protobuf框架代码
// #include "base.pb.h"  // protobuf框架代码
// #include "file.pb.h"  // protobuf框架代码

// namespace mag
// {
// class UserServiceImpl : public mag::UserService
// {
//     public:
//         ////////////////////////////////////////////////
//         ///初始化 ES 用户管理、MySQL 用户表、Redis 会话、状态和验证码管理
//         ///创建ES索引
//         ///////////////////////////////////////////////
//         UserServiceImpl(const DMSClient::ptr &dms_client,
//             const std::shared_ptr<elasticlient::Client> &es_client,
//             const std::shared_ptr<odb::core::database> &mysql_client,
//             const std::shared_ptr<sw::redis::Redis> &redis_client,
//             const ServiceManager::ptr &channel_manager,
//             const std::string &file_service_name) :
//             _es_user(std::make_shared<ESUser>(es_client)),
//             _mysql_user(std::make_shared<UserTable>(mysql_client)),
//             _redis_session(std::make_shared<Session>(redis_client)),
//             _redis_status(std::make_shared<Status>(redis_client)),
//             _redis_codes(std::make_shared<Codes>(redis_client)),
//             _file_service_name(file_service_name),
//             _mm_channels(channel_manager),
//             _dms_client(dms_client){
//                 _es_user->createIndex();
//             }
//         ~UserServiceImpl(){}

//         ////////////////////////////////////////////////
//         ///辅助函数
//         ///////////////////////////////////////////////

//         //检查昵称长度是否小于22个字符
//         bool nickname_check(const std::string &nickname) {
//             return nickname.size() < 22;
//         }
//         //检查密码长度
//         bool password_check(const std::string &password) {
//             if(password.size() < 6 || password.size()>15){
//                 LOG_ERROR("密码长度不合法：{}-{}", password, password.size());
//                 return false;
//             }
//             for (int i = 0; i < password.size(); i++) {
//                 if (!((password[i] > 'a' && password[i] < 'z') ||
//                 (password[i] > 'A' && password[i] < 'Z') ||
//                 (password[i] > '0' && password[i] < '9') ||
//                 password[i] == '_' || password[i] == '-')) {
//                 LOG_ERROR("密码字符不合法：{}", password);
//                 return false;
//             }
//         }
//             return true;
//         }

//         //检查手机号码
//         bool phone_check(const std::string &phone) {
//             if (phone.size() != 11) return false;
//             if (phone[0] != '1') return false;
//             if (phone[1] < '3' || phone[1] > '9') return false;
//             for (int i = 2; i < 11; i++) {
//                 if (phone[i] < '0' || phone[i] > '9') return false;
//             }
//             return true;
//         }

//         ////////////////////////////////////////////////
//         ///RPC方法实现
//         ///////////////////////////////////////////////

//         //用户注册
//         virtual void UserRegister(::google::protobuf::RpcController* controller,
//             const ::mag::UserRegisterReq* request,
//             ::mag::UserRegisterRsp* response,
//             ::google::protobuf::Closure* done) {
//             // 日志记录和错误处理
//             LOG_DEBUG("收到用户注册请求！");
//             brpc::ClosureGuard rpc_guard(done);
//             auto err_response = [this, response](const std::string &rid, 
//                 const std::string &errmsg) -> void {
//                 response->set_request_id(rid);
//                 response->set_success(false);
//                 response->set_errmsg(errmsg);
//                 return;
//             };
            
//             // 1. 提取昵称和密码
//             std::string nickname = request->nickname();
//             std::string password = request->password();
            
//             // 2. 检查昵称合法性
//             bool ret = nickname_check(nickname);
//             if (!ret) {
//                 LOG_ERROR("{} - 用户名长度不合法！", request->request_id());
//                 return err_response(request->request_id(), "用户名长度不合法！");
//             }
            
//             // 3. 检查密码合法性
//             ret = password_check(password);
//             if (!ret) {
//                 LOG_ERROR("{} - 密码格式不合法！", request->request_id());
//                 return err_response(request->request_id(), "密码格式不合法！");
//             }
            
//             // 4. 检查昵称是否已存在
//             auto user = _mysql_user->select_by_nickname(nickname);
//             if (user) {
//                 LOG_ERROR("{} - 用户名被占用- {}！", request->request_id(), nickname);
//                 return err_response(request->request_id(), "用户名被占用!");
//             }
            
//             // 5. 向数据库新增用户
//             std::string uid = uuid();
//             user = std::make_shared<User>(uid, nickname, password);
//             ret = _mysql_user->insert(user);
//             if (!ret) {
//                 LOG_ERROR("{} - Mysql数据库新增数据失败！", request->request_id());
//                 return err_response(request->request_id(), "Mysql数据库新增数据失败!");
//             }
            
//             // 6. 向 ES 服务器新增用户信息
//             ret = _es_user->appendData(uid, "", nickname, "", "");
//             if (!ret) {
//                 LOG_ERROR("{} - ES搜索引擎新增数据失败！", request->request_id());
//                 return err_response(request->request_id(), "ES搜索引擎新增数据失败！");
//             }
            
//             // 7. 组织成功响应
//             response->set_request_id(request->request_id());
//             response->set_success(true);
//         }

//         //用户登录
//         virtual void UserLogin(::google::protobuf::RpcController* controller,
//             const ::mag::UserLoginReq* request,
//             ::mag::UserLoginRsp* response,
//             ::google::protobuf::Closure* done){
//             // 日志记录和错误处理
//             LOG_DEBUG("收到用户登录请求！");
//             brpc::ClosureGuard rpc_guard(done);
//             auto err_response = [this, response](const std::string &rid, 
//                 const std::string &errmsg) -> void {
//                 response->set_request_id(rid);
//                 response->set_success(false);
//                 response->set_errmsg(errmsg);
//                 return;
//             };
            
//             // 1. 提取昵称和密码
//             std::string nickname = request->nickname();
//             std::string password = request->password();
            
//             // 2. 验证用户信息
//             auto user = _mysql_user->select_by_nickname(nickname);
//             if (!user || password != user->password()) {
//                 LOG_ERROR("{} - 用户名或密码错误 - {}-{}！", request->request_id(), nickname, password);
//                 return err_response(request->request_id(), "用户名或密码错误!");
//             }
            
//             // 3. 检查用户是否已登录
//             bool ret = _redis_status->exists(user->user_id());
//             if (ret) {
//                 LOG_ERROR("{} - 用户已在其他地方登录 - {}！", request->request_id(), nickname);
//                 return err_response(request->request_id(), "用户已在其他地方登录!");
//             }
            
//             // 4. 生成会话ID并存储会话信息
//             std::string ssid = uuid();
//             _redis_session->append(ssid, user->user_id());
            
//             // 5. 添加用户登录标记
//             _redis_status->append(user->user_id());
            
//             // 6. 返回成功响应
//             response->set_request_id(request->request_id());
//             response->set_login_session_id(ssid);
//             response->set_success(true);
//         }

        
//         //获取手机验证码
//         virtual void GetPhoneVerifyCode(::google::protobuf::RpcController* controller,
//             const ::mag::PhoneVerifyCodeReq* request,
//             ::mag::PhoneVerifyCodeRsp* response,
//             ::google::protobuf::Closure* done){
//                 LOG_DEBUG("收到短信验证码获取请求！");
//                 brpc::ClosureGuard rpc_guard(done);
//                 auto err_response = [this, response](const std::string &rid, 
//                     const std::string &errmsg) -> void {
//                     response->set_request_id(rid);
//                     response->set_success(false);
//                     response->set_errmsg(errmsg);
//                     return;
//                 };

//                 //1. 请求中获取手机号并验证
//                 std::string phone = request->phone_number();
//                 bool ret = phone_check(phone);
//                 if(ret == false){
//                     LOG_ERROR("{} - 手机号码格式错误 - {}！", request->request_id(), phone);
//                     return err_response(request->request_id(),"手机号码格式错误");
//                 }

//                 // 2.生成4位验证码
//                 std::string code_id = uuid();
//                 std::string code = vcode();

//                 //3. 发送验证码
//                 ret = _dms_client->send(phone, code);
//                 if (ret == false) {
//                     LOG_ERROR("{} - 短信验证码发送失败 - {}！", request->request_id(), phone);
//                     return err_response(request->request_id(), "短信验证码发送失败!");
//                 }

//                 //4. 构造验证码ID然后添加到Redis中
//                 _redis_codes->append(code_id,code);
//                 //5. 组织响应，返回生成的验证ID
//                 response->set_request_id(request->request_id());
//                 response->set_success(true);
//                 response->set_verify_code_id(code_id);
//                 LOG_DEBUG("获取短信验证码处理完成！");
//             }

//         virtual void PhoneRegister(::google::protobuf::RpcController* controller,
//             const ::mag::PhoneRegisterReq* request,
//             ::mag::PhoneRegisterRsp* response,
//             ::google::protobuf::Closure* done){
//                 LOG_DEBUG("收到手机号注册请求！");
//                 brpc::ClosureGuard rpc_guard(done);
//                 auto err_response = [this, response](const std::string &rid, 
//                     const std::string &errmsg) -> void {
//                     response->set_request_id(rid);
//                     response->set_success(false);
//                     response->set_errmsg(errmsg);
//                     return;
//                 };
//                 // 1. 从请求中取出手机号码和验证码,验证码ID
//                 std::string phone = request->phone_number();
//                 std::string code_id = request->verify_code_id();
//                 std::string code = request->verify_code();
//                 // 2. 检查注册手机号码是否合法
//                 bool ret = phone_check(phone);
//                 if (ret == false) {
//                     LOG_ERROR("{} - 手机号码格式错误 - {}！", request->request_id(), phone);
//                     return err_response(request->request_id(), "手机号码格式错误!");
//                 }
//                 // 3. 从 redis 数据库中进行验证码 ID-验证码一致性匹配
//                 auto vcode = _redis_codes->code(code_id);
//                 if (vcode != code) {
//                     LOG_ERROR("{} - 验证码错误 - {}-{}！", request->request_id(), code_id, code);
//                     return err_response(request->request_id(), "验证码错误!");
//                 }
//                 // 4. 通过数据库查询判断手机号是否已经注册过
//                 auto user = _mysql_user->select_by_phone(phone);
//                 if (user) {
//                     LOG_ERROR("{} - 该手机号已注册过用户 - {}！", request->request_id(), phone);
//                     return err_response(request->request_id(), "该手机号已注册过用户!");
//                 }
//                 // 5. 向数据库新增用户信息
//                 std::string uid = uuid();
//                 user = std::make_shared<User>(uid, phone);
//                 ret = _mysql_user->insert(user);
//                 if (ret == false) {
//                     LOG_ERROR("{} - 向数据库添加用户信息失败 - {}！", request->request_id(), phone);
//                     return err_response(request->request_id(), "向数据库添加用户信息失败!");
//                 }
//                 // 6. 向 ES 服务器中新增用户信息
//                 ret = _es_user->appendData(uid, phone, uid, "", "");
//                 if (ret == false) {
//                     LOG_ERROR("{} - ES搜索引擎新增数据失败！", request->request_id());
//                     return err_response(request->request_id(), "ES搜索引擎新增数据失败！");
//                 }
//                 //7. 组织响应，进行成功与否的响应即可。
//                 response->set_request_id(request->request_id());
//                 response->set_success(true);
//             }

//         virtual void PhoneLogin(::google::protobuf::RpcController* controller,
//             const ::mag::PhoneLoginReq* request,
//             ::mag::PhoneLoginRsp* response,
//             ::google::protobuf::Closure* done){
//                 LOG_DEBUG("收到手机号登录请求！");
//                 brpc::ClosureGuard rpc_guard(done);
//                 auto err_response = [this, response](const std::string &rid, 
//                     const std::string &errmsg) -> void {
//                     response->set_request_id(rid);
//                     response->set_success(false);
//                     response->set_errmsg(errmsg);
//                     return;
//                 };
//                 // 1. 从请求中取出手机号码和验证码 ID，以及验证码。
//                 std::string phone = request->phone_number();
//                 std::string code_id = request->verify_code_id();
//                 std::string code = request->verify_code();
//                 // 2. 检查注册手机号码是否合法
//                 bool ret = phone_check(phone);
//                 if (ret == false) {
//                     LOG_ERROR("{} - 手机号码格式错误 - {}！", request->request_id(), phone);
//                     return err_response(request->request_id(), "手机号码格式错误!");
//                 }
//                 // 3. 根据手机号从数据数据进行用户信息查询，判断用用户是否存在
//                 auto user = _mysql_user->select_by_phone(phone);
//                 if (!user) {
//                     LOG_ERROR("{} - 该手机号未注册用户 - {}！", request->request_id(), phone);
//                     return err_response(request->request_id(), "该手机号未注册用户!");
//                 }
//                 // 4. 从 redis 数据库中进行验证码 ID-验证码一致性匹配
//                 auto vcode = _redis_codes->code(code_id);
//                 if (vcode != code) {
//                     LOG_ERROR("{} - 验证码错误 - {}-{}！", request->request_id(), code_id, code);
//                     return err_response(request->request_id(), "验证码错误!");
//                 }
//                 _redis_codes->remove(code_id);
//                 // 5. 根据 redis 中的登录标记信息是否存在判断用户是否已经登录。
//                 ret = _redis_status->exists(user->user_id());
//                 if (ret == true) {
//                     LOG_ERROR("{} - 用户已在其他地方登录 - {}！", request->request_id(), phone);
//                     return err_response(request->request_id(), "用户已在其他地方登录!");
//                 }
//                 //4. 构造会话 ID，生成会话键值对，向 redis 中添加会话信息以及登录标记信息
//                 std::string ssid = uuid();
//                 _redis_session->append(ssid, user->user_id());
//                 //5. 添加用户登录信息
//                 _redis_status->append(user->user_id());
//                 // 7. 组织响应，返回生成的会话 ID
//                 response->set_request_id(request->request_id());
//                 response->set_login_session_id(ssid);
//                 response->set_success(true);
//             }
//         //获取用户信息
//         virtual void GetUserInfo(::google::protobuf::RpcController* controller,
//             const ::mag::GetUserInfoReq* request,
//             ::mag::GetUserInfoRsp* response,
//             ::google::protobuf::Closure* done){
//                 // 日志记录和错误处理
//                 LOG_DEBUG("收到获取单个用户信息请求！");
//                 brpc::ClosureGuard rpc_guard(done);
//                 auto err_response = [this, response](const std::string &rid, 
//                     const std::string &errmsg) -> void {
//                     response->set_request_id(rid);
//                     response->set_success(false);
//                     response->set_errmsg(errmsg);
//                     return;
//                 };

//                 //1. 提取用户ID
//                 std::string uid = request->user_id();

//                 //2. 从数据库中查询用户信息
//                 auto user = _mysql_user->select_by_id(uid);
//                 if(!user){
//                     LOG_ERROR("{} - 未找到用户信息 - {}！", request->request_id(), uid);
//                     return err_response(request->request_id(), "未找到用户信息!");
//                 }

//                 //3. 获取用户头像
//                 UserInfo *user_info = response->mutable_user_info();
//                 user_info->set_user_id(user->user_id());
//                 user_info->set_nickname(user->nickname());
//                 user_info->set_description(user->description());
//                 user_info->set_phone(user->phone());

//                 if (!user->avatar_id().empty()) {
//                 auto channel = _mm_channels->choose(_file_service_name);
//                 if (!channel) {
//                     LOG_ERROR("{} - 未找到文件管理子服务节点 - {} - {}！", 
//                         request->request_id(), _file_service_name, uid);
//                     return err_response(request->request_id(), "未找到文件管理子服务节点!");
//                 }
//                 mag::FileService_Stub stub(channel.get());
//                 mag::GetSingleFileReq req;
//                 mag::GetSingleFileRsp rsp;
//                 req.set_request_id(request->request_id());
//                 req.set_file_id(user->avatar_id());
//                 brpc::Controller cntl;
//                 stub.GetSingleFile(&cntl, &req, &rsp, nullptr);
//                 if (cntl.Failed() || !rsp.success()) {
//                     LOG_ERROR("{} - 文件子服务调用失败：{}！", request->request_id(), cntl.ErrorText());
//                     return err_response(request->request_id(), "文件子服务调用失败!");
//                 }
//                 user_info->set_avatar(rsp.file_data().file_content());
//             }
            
//             // 4. 返回成功响应
//             response->set_request_id(request->request_id());
//             response->set_success(true);
//         }  

//         virtual void GetMultiUserInfo(::google::protobuf::RpcController* controller,
//             const ::mag::GetMultiUserInfoReq* request,
//             ::mag::GetMultiUserInfoRsp* response,
//             ::google::protobuf::Closure* done){
//                 LOG_DEBUG("收到批量用户信息获取请求！");
//                 brpc::ClosureGuard rpc_guard(done);
//                 //1. 定义错误回调
//                 auto err_response = [this, response](const std::string &rid, 
//                     const std::string &errmsg) -> void {
//                     response->set_request_id(rid);
//                     response->set_success(false);
//                     response->set_errmsg(errmsg);
//                     return;
//                 };
//                 //2. 从请求中取出用户ID --- 列表
//                 std::vector<std::string> uid_lists;
//                 for (int i = 0; i < request->users_id_size(); i++) {
//                     uid_lists.push_back(request->users_id(i));
//                 }
//                 //3. 从数据库进行批量用户信息查询
//                 auto users = _mysql_user->select_multi_users(uid_lists);
//                 if (users.size() != request->users_id_size()) {
//                     LOG_ERROR("{} - 从数据库查找的用户信息数量不一致 {}-{}！", 
//                         request->request_id(), request->users_id_size(), users.size());
//                     return err_response(request->request_id(), "从数据库查找的用户信息数量不一致!");
//                 }
//                 //4. 批量从文件管理子服务进行文件下载
//                 auto channel = _mm_channels->choose(_file_service_name);
//                 if (!channel) {
//                     LOG_ERROR("{} - 未找到文件管理子服务节点 - {}！", request->request_id(), _file_service_name);
//                     return err_response(request->request_id(), "未找到文件管理子服务节点!");
//                 }
//                 mag::FileService_Stub stub(channel.get());
//                 mag::GetMultiFileReq req;
//                 mag::GetMultiFileRsp rsp;
//                 req.set_request_id(request->request_id());
//                 for (auto &user : users) {
//                     if (user.avatar_id().empty()) continue;
//                     req.add_file_id_list(user.avatar_id());
//                 }
//                 brpc::Controller cntl;
//                 stub.GetMultiFile(&cntl, &req, &rsp, nullptr);
//                 if (cntl.Failed() == true || rsp.success() == false) {
//                     LOG_ERROR("{} - 文件子服务调用失败：{} - {}！", request->request_id(), 
//                         _file_service_name, cntl.ErrorText());
//                     return err_response(request->request_id(), "文件子服务调用失败!");
//                 }
//                 //5. 组织响应（）
//                 for (auto &user : users) {
//                     auto user_map = response->mutable_users_info();//本次请求要响应的用户信息map
//                     auto file_map = rsp.mutable_file_data(); //这是批量文件请求响应中的map 
//                     UserInfo user_info;
//                     user_info.set_user_id(user.user_id());
//                     user_info.set_nickname(user.nickname());
//                     user_info.set_description(user.description());
//                     user_info.set_phone(user.phone());
//                     user_info.set_avatar((*file_map)[user.avatar_id()].file_content());
//                     (*user_map)[user_info.user_id()] = user_info;
//                 }
//                 response->set_request_id(request->request_id());
//                 response->set_success(true);
//             }

//         virtual void SetUserAvatar(::google::protobuf::RpcController* controller,
//             const ::mag::SetUserAvatarReq* request,
//             ::mag::SetUserAvatarRsp* response,
//             ::google::protobuf::Closure* done){
//                 LOG_DEBUG("收到用户头像设置请求！");
//                 brpc::ClosureGuard rpc_guard(done);
//                 auto err_response = [this, response](const std::string &rid, 
//                     const std::string &errmsg) -> void {
//                     response->set_request_id(rid);
//                     response->set_success(false);
//                     response->set_errmsg(errmsg);
//                     return;
//                 };
//                 // 1. 从请求中取出用户 ID 与头像数据
//                 std::string uid = request->user_id();
//                 // 2. 从数据库通过用户 ID 进行用户信息查询，判断用户是否存在
//                 auto user = _mysql_user->select_by_id(uid);
//                 if (!user) {
//                     LOG_ERROR("{} - 未找到用户信息 - {}！", request->request_id(), uid);
//                     return err_response(request->request_id(), "未找到用户信息!");
//                 }
//                 // 3. 上传头像文件到文件子服务，
//                 auto channel = _mm_channels->choose(_file_service_name);
//                 if (!channel) {
//                     LOG_ERROR("{} - 未找到文件管理子服务节点 - {}！", request->request_id(), _file_service_name);
//                     return err_response(request->request_id(), "未找到文件管理子服务节点!");
//                 }
//                 mag::FileService_Stub stub(channel.get());
//                 mag::PutSingleFileReq req;
//                 mag::PutSingleFileRsp rsp;
//                 req.set_request_id(request->request_id());
//                 req.mutable_file_data()->set_file_name("");
//                 req.mutable_file_data()->set_file_size(request->avatar().size());
//                 req.mutable_file_data()->set_file_content(request->avatar());
//                 brpc::Controller cntl;
//                 stub.PutSingleFile(&cntl, &req, &rsp, nullptr);
//                 if (cntl.Failed() == true || rsp.success() == false) {
//                     LOG_ERROR("{} - 文件子服务调用失败：{}！", request->request_id(), cntl.ErrorText());
//                     return err_response(request->request_id(), "文件子服务调用失败!");
//                 }
//                 std::string avatar_id = rsp.file_info().file_id();
//                 // 4. 将返回的头像文件 ID 更新到数据库中
//                 user->avatar_id(avatar_id);
//                 bool ret = _mysql_user->update(user);
//                 if (ret == false) {
//                     LOG_ERROR("{} - 更新数据库用户头像ID失败 ：{}！", request->request_id(), avatar_id);
//                     return err_response(request->request_id(), "更新数据库用户头像ID失败!");
//                 }
//                 // 5. 更新 ES 服务器中用户信息
//                 ret = _es_user->appendData(user->user_id(), user->phone(),
//                     user->nickname(), user->description(), user->avatar_id());
//                 if (ret == false) {
//                     LOG_ERROR("{} - 更新搜索引擎用户头像ID失败 ：{}！", request->request_id(), avatar_id);
//                     return err_response(request->request_id(), "更新搜索引擎用户头像ID失败!");
//                 }
//                 // 6. 组织响应，返回更新成功与否
//                 response->set_request_id(request->request_id());
//                 response->set_success(true);
//             }

//         virtual void SetUserNickname(::google::protobuf::RpcController* controller,
//             const ::mag::SetUserNicknameReq* request,
//             ::mag::SetUserNicknameRsp* response,
//             ::google::protobuf::Closure* done){
//                  LOG_DEBUG("收到用户昵称设置请求！");
//                 brpc::ClosureGuard rpc_guard(done);
//                 auto err_response = [this, response](const std::string &rid, 
//                     const std::string &errmsg) -> void {
//                     response->set_request_id(rid);
//                     response->set_success(false);
//                     response->set_errmsg(errmsg);
//                     return;
//                 };
//                 // 1. 从请求中取出用户 ID 与新的昵称
//                 std::string uid = request->user_id();
//                 std::string new_nickname = request->nickname();
//                 // 2. 判断昵称格式是否正确
//                 bool ret = nickname_check(new_nickname);
//                 if (ret == false) {
//                     LOG_ERROR("{} - 用户名长度不合法！", request->request_id());
//                     return err_response(request->request_id(), "用户名长度不合法！");
//                 }
//                 // 3. 从数据库通过用户 ID 进行用户信息查询，判断用户是否存在
//                 auto user = _mysql_user->select_by_id(uid);
//                 if (!user) {
//                     LOG_ERROR("{} - 未找到用户信息 - {}！", request->request_id(), uid);
//                     return err_response(request->request_id(), "未找到用户信息!");
//                 }
//                 // 4. 将新的昵称更新到数据库中
//                 user->nickname(new_nickname);
//                 ret = _mysql_user->update(user);
//                 if (ret == false) {
//                     LOG_ERROR("{} - 更新数据库用户昵称失败 ：{}！", request->request_id(), new_nickname);
//                     return err_response(request->request_id(), "更新数据库用户昵称失败!");
//                 }
//                 // 5. 更新 ES 服务器中用户信息
//                 ret = _es_user->appendData(user->user_id(), user->phone(),
//                     user->nickname(), user->description(), user->avatar_id());
//                 if (ret == false) {
//                     LOG_ERROR("{} - 更新搜索引擎用户昵称失败 ：{}！", request->request_id(), new_nickname);
//                     return err_response(request->request_id(), "更新搜索引擎用户昵称失败!");
//                 }
//                 // 6. 组织响应，返回更新成功与否
//                 response->set_request_id(request->request_id());
//                 response->set_success(true);
//             }

//         virtual void SetUserDescription(::google::protobuf::RpcController* controller,
//             const ::mag::SetUserDescriptionReq* request,
//             ::mag::SetUserDescriptionRsp* response,
//             ::google::protobuf::Closure* done){
//                  LOG_DEBUG("收到用户签名设置请求！");
//                 brpc::ClosureGuard rpc_guard(done);
//                 auto err_response = [this, response](const std::string &rid, 
//                     const std::string &errmsg) -> void {
//                     response->set_request_id(rid);
//                     response->set_success(false);
//                     response->set_errmsg(errmsg);
//                     return;
//                 };
//                 // 1. 从请求中取出用户 ID 与新的昵称
//                 std::string uid = request->user_id();
//                 std::string new_description = request->description();
//                 // 3. 从数据库通过用户 ID 进行用户信息查询，判断用户是否存在
//                 auto user = _mysql_user->select_by_id(uid);
//                 if (!user) {
//                     LOG_ERROR("{} - 未找到用户信息 - {}！", request->request_id(), uid);
//                     return err_response(request->request_id(), "未找到用户信息!");
//                 }
//                 // 4. 将新的昵称更新到数据库中
//                 user->description(new_description);
//                 bool ret = _mysql_user->update(user);
//                 if (ret == false) {
//                     LOG_ERROR("{} - 更新数据库用户签名失败 ：{}！", request->request_id(), new_description);
//                     return err_response(request->request_id(), "更新数据库用户签名失败!");
//                 }
//                 // 5. 更新 ES 服务器中用户信息
//                 ret = _es_user->appendData(user->user_id(), user->phone(),
//                     user->nickname(), user->description(), user->avatar_id());
//                 if (ret == false) {
//                     LOG_ERROR("{} - 更新搜索引擎用户签名失败 ：{}！", request->request_id(), new_description);
//                     return err_response(request->request_id(), "更新搜索引擎用户签名失败!");
//                 }
//                 // 6. 组织响应，返回更新成功与否
//                 response->set_request_id(request->request_id());
//                 response->set_success(true);
//             }

//         virtual void SetUserPhoneNumber(::google::protobuf::RpcController* controller,
//             const ::mag::SetUserPhoneNumberReq* request,
//             ::mag::SetUserPhoneNumberRsp* response,
//             ::google::protobuf::Closure* done){
//                  LOG_DEBUG("收到用户手机号设置请求！");
//                 brpc::ClosureGuard rpc_guard(done);
//                 auto err_response = [this, response](const std::string &rid, 
//                     const std::string &errmsg) -> void {
//                     response->set_request_id(rid);
//                     response->set_success(false);
//                     response->set_errmsg(errmsg);
//                     return;
//                 };
//                 // 1. 从请求中取出用户 ID 与新的昵称
//                 std::string uid = request->user_id();
//                 std::string new_phone = request->phone_number();
//                 std::string code = request->phone_verify_code();
//                 std::string code_id = request->phone_verify_code_id();
//                 // 2. 对验证码进行验证
//                 auto vcode = _redis_codes->code(code_id);
//                 if (vcode != code) {
//                     LOG_ERROR("{} - 验证码错误 - {}-{}！", request->request_id(), code_id, code);
//                     return err_response(request->request_id(), "验证码错误!");
//                 }
//                 // 3. 从数据库通过用户 ID 进行用户信息查询，判断用户是否存在
//                 auto user = _mysql_user->select_by_id(uid);
//                 if (!user) {
//                     LOG_ERROR("{} - 未找到用户信息 - {}！", request->request_id(), uid);
//                     return err_response(request->request_id(), "未找到用户信息!");
//                 }
//                 // 4. 将新的昵称更新到数据库中
//                 user->phone(new_phone);
//                 bool ret = _mysql_user->update(user);
//                 if (ret == false) {
//                     LOG_ERROR("{} - 更新数据库用户手机号失败 ：{}！", request->request_id(), new_phone);
//                     return err_response(request->request_id(), "更新数据库用户手机号失败!");
//                 }
//                 // 5. 更新 ES 服务器中用户信息
//                 ret = _es_user->appendData(user->user_id(), user->phone(),
//                     user->nickname(), user->description(), user->avatar_id());
//                 if (ret == false) {
//                     LOG_ERROR("{} - 更新搜索引擎用户手机号失败 ：{}！", request->request_id(), new_phone);
//                     return err_response(request->request_id(), "更新搜索引擎用户手机号失败!");
//                 }
//                 // 6. 组织响应，返回更新成功与否
//                 response->set_request_id(request->request_id());
//                 response->set_success(true);
//             }

//     private:
//         // std::make_shared<elasticclient::Client> _es_client;
//         // std::shared_ptr<odb::core::Database> _mysql_client;
//         // std::shared_ptr<sw::redis::Redis> _redis_client;
        
//         // ESUser::ptr _es_user;
//         // UserTable::ptr _mysql_user;
//         // Session::ptr _redis_session;
//         // Status::ptr _redis_status;
//         // Codes::ptr _redis_codes;
        
//         // std::make_shared<ServiceManager> _mm_channels;
//         // Discovery::ptr _service_discoverer;


//         ESUser::ptr _es_user;
//         UserTable::ptr _mysql_user;
//         Session::ptr _redis_session;
//         Status::ptr _redis_status;
//         Codes::ptr _redis_codes;
//         //这边是rpc调用客户端相关对象
//         std::string _file_service_name;
//         ServiceManager::ptr _mm_channels;
//         DMSClient::ptr _dms_client;
// };


// ////////////////////////////////////////////////////
// ///封装RPC服务器及其组件，提供方法启动服务器
// ///////////////////////////////////////////////////

// class UserServer {
//     public:
//         using ptr = std::shared_ptr<UserServer>;
//         UserServer(const Discovery::ptr service_discoverer, 
//             const Registry::ptr &reg_client,
//             const std::shared_ptr<elasticlient::Client> &es_client,
//             const std::shared_ptr<odb::core::database> &mysql_client,
//             std::shared_ptr<sw::redis::Redis> &redis_client,
//             const std::shared_ptr<brpc::Server> &server):
//             _service_discoverer(service_discoverer),
//             _registry_client(reg_client),
//             _es_client(es_client),
//             _mysql_client(mysql_client),
//             _redis_client(redis_client),
//             _rpc_server(server){}
//         ~UserServer(){}
        
//         // 启动RPC服务器
//         void start() {
//             _rpc_server->RunUntilAskedToQuit();
//         }
//     private:
//         Discovery::ptr _service_discoverer; //服务发现
//         Registry::ptr _registry_client;     //服务注册
//         std::shared_ptr<elasticlient::Client> _es_client;   //Elasticsearch客户端
//         std::shared_ptr<odb::core::database> _mysql_client; //MySQL客户端
//         std::shared_ptr<sw::redis::Redis> _redis_client;    //Redis客户端
//         std::shared_ptr<brpc::Server> _rpc_server;          //brpc服务器
// };

// ////////////////////////////////////////////////////
// ///建造者类，构建UserServer所需要的各个组件
// ///////////////////////////////////////////////////

// class UserServerBuilder {
// public:
//     //创建 Elasticsearch 客户端
//     void make_es_object(const std::vector<std::string> host_list) {
//         _es_client = ESClientFactory::create(host_list);
//     }
//     // 创建短信服务客户端（DMS）
//     void make_dms_object(const std::string &access_key_id,
//         const std::string &access_key_secret) {
//         _dms_client = std::make_shared<DMSClient>(access_key_id, access_key_secret);
//     }
//     // 创建 MySQL 客户端，支持连接池
//     void make_mysql_object(
//         const std::string &user,
//         const std::string &pswd,
//         const std::string &host,
//         const std::string &db,
//         const std::string &cset,
//         int port,
//         int conn_pool_count) {
//         _mysql_client = ODBFactory::create(user, pswd, host, db, cset, port, conn_pool_count);
//     }
//     // 创建 Redis 客户端
//     void make_redis_object(const std::string &host,
//         int port,
//         int db,
//         bool keep_alive) {
//         _redis_client = RedisClientFactory::create(host, port, db, keep_alive);
//     }
//     // 创建服务发现客户端，并设置文件服务名称及信道管理回调
//     void make_discovery_object(const std::string &reg_host,
//         const std::string &base_service_name,
//         const std::string &file_service_name) {
//         _file_service_name = file_service_name;
//         _mm_channels = std::make_shared<ServiceManager>();
//         _mm_channels->declared(file_service_name);
//         LOG_DEBUG("设置文件子服务为需添加管理的子服务：{}", file_service_name);
//         auto put_cb = std::bind(&ServiceManager::onServiceOnline, _mm_channels.get(), std::placeholders::_1, std::placeholders::_2);
//         auto del_cb = std::bind(&ServiceManager::onServiceOffline, _mm_channels.get(), std::placeholders::_1, std::placeholders::_2);
//         _service_discoverer = std::make_shared<Discovery>(reg_host, base_service_name, put_cb, del_cb);
//     }
//     // 创建服务注册客户端，并注册服务到注册中心
//    void make_registry_object(const std::string &reg_host,
//     const std::string &service_name,
//     const std::string &access_host){
//         _registry_client = std::make_shared<Registry>(reg_host);
//         _registry_client->registry(service_name, access_host);
//     } 
//     // 检查所有依赖是否已构造，创建 brpc 服务器
//     void make_rpc_server(uint16_t port, int32_t timeout, uint8_t num_threads)
//     {
//         // 检查依赖组件是否已构造
//         if (!_es_client) {
//             LOG_ERROR("还未初始化ES搜索引擎模块！");
//             abort();
//         }
//         if (!_mysql_client) {
//             LOG_ERROR("还未初始化Mysql数据库模块！");
//             abort();
//         }
//         if (!_redis_client) {
//             LOG_ERROR("还未初始化Redis数据库模块！");
//             abort();
//         }
//         if (!_mm_channels) {
//             LOG_ERROR("还未初始化信道管理模块！");
//             abort();
//         }
//         if (!_dms_client) {
//             LOG_ERROR("还未初始化短信平台模块！");
//             abort();
//         }

//         _rpc_server = std::make_shared<brpc::Server>();

//         //创建并添加USerServiceImpl
//         UserServiceImpl *user_service = new UserServiceImpl(_dms_client, _es_client,
//         _mysql_client, _redis_client, _mm_channels, _file_service_name);
//         int ret = _rpc_server->AddService(user_service, 
//             brpc::ServiceOwnership::SERVER_OWNS_SERVICE);
//         if (ret == -1) {
//             LOG_ERROR("添加Rpc服务失败！");
//             abort();
//         }

//         // 创建并添加 SpeechRecognitionServiceImpl（假设已实现）
//         SpeechRecognitionServiceImpl* speech_service = new SpeechRecognitionServiceImpl();
//         ret = _rpc_server->AddService(speech_service,
//         brpc::ServiceOwnership::SERVER_OWNS_SERVICE);
//         if (ret == -1) {
//             LOG_ERROR("添加语音识别Rpc服务失败！");
//             abort();
//         }

//         // 启动RPC服务器
//         brpc::ServerOptions options;
//         options.idle_timeout_sec = timeout;
//         options.num_threads = num_threads;
//         ret = _rpc_server->Start(port, &options);
//         if (ret == -1) {
//             LOG_ERROR("服务启动失败！");
//             abort();
//         }
//     }
    
//     ///构建RPC服务器
//     UserServer::ptr build() {
//         if (!_service_discoverer) {
//             LOG_ERROR("还未初始化服务发现模块！");
//             abort();
//         }
//         if (!_registry_client) {
//             LOG_ERROR("还未初始化服务注册模块！");
//             abort();
//         }
//         if (!_rpc_server) {
//             LOG_ERROR("还未初始化RPC服务器模块！");
//             abort();
//         }
//         UserServer::ptr server = std::make_shared<UserServer>(
//             _service_discoverer, _registry_client,
//             _es_client, _mysql_client, _redis_client, _rpc_server);
//         return server;
//     }

// private:
//     Registry::ptr _registry_client;

//     std::shared_ptr<elasticlient::Client> _es_client;
//     std::shared_ptr<odb::core::database> _mysql_client;
//     std::shared_ptr<sw::redis::Redis> _redis_client;

//     std::string _file_service_name;
//     ServiceManager::ptr _mm_channels;
//     Discovery::ptr _service_discoverer;

//     std::shared_ptr<DMSClient> _dms_client;

//     std::shared_ptr<brpc::Server> _rpc_server;
// };


// }